#include "Concurrent_queue.h"


Concurrent_queue::Concurrent_queue()
{
	mtx_init(&the_mutex, mtx_plain);
	cnd_init(&the_condition_variable);
}

Concurrent_queue::	~Concurrent_queue()
{
	mtx_destroy(&the_mutex);
	cnd_destroy(&the_condition_variable);
}

void Concurrent_queue::push(thrd_t const& data)
{
	mtx_lock(&the_mutex);
	the_queue.push(data);
	mtx_unlock(&the_mutex);
	cnd_signal(&the_condition_variable);
}

bool Concurrent_queue::empty()
{
	mtx_lock(&the_mutex);
	return the_queue.empty();
}

bool Concurrent_queue::try_pop(thrd_t& popped_value)
{
	mtx_lock(&the_mutex);
	if (the_queue.empty())
	{
		return false;
	}

	popped_value = the_queue.front();
	the_queue.pop();
	return true;
}

void Concurrent_queue::wait_and_pop(thrd_t& popped_value)
{
	mtx_lock(&the_mutex);
	while (the_queue.empty())
	{
		cnd_wait(&the_condition_variable, &the_mutex);
	}

	popped_value = the_queue.front();
	the_queue.pop();
}
